<html>
    <head>
        <title>实现了IConcurrencyChecker接口的基类</title>
    </head>
    <body>
        <script>
            /*
                        三、实现了IConcurrencyChecker接口的基类

                                     聚合根实体类已经实现了IHasConcurrencyStamp接口。
                                     
                                     因此，如果你是从这些基类之一派生的，则不需要手动实现IHasConcurrencyStamp接口：

                                          ①、AggregateRoot, AggregateRoot<TKey> AggregateRoot，AggregateRoot<TKey>

                                          ②、CreationAuditedAggregateRoot，CreationAuditedAggregateRoot<TKey>

                                          ③、AuditedAggregateRoot，AuditedAggregateRoot<TKey>

                                          ④、FullAuditedAggregateRoot，FullAuditedAggregateRoot<TKey>


                                    eg：
                                        为图书实体应用并发控制

                                        你可以从基类之一继承你的实体：

                                            public class Book : FullAuditedAggregateRoot<Guid>
                                            {
                                                //...
                                            }

                                        然后，输入、输出Dto

                                            public class BookDto : EntityDto<Guid>, IHasConcurrencyStamp 
                                            {
                                                //...

                                                public string ConcurrencyStamp { get; set; }
                                            }

                                            public class UpdateBookDto : IHasConcurrencyStamp 
                                            {
                                                //...

                                                public string ConcurrencyStamp { get; set; }
                                            }   

                                        应用程序服务的UpdateAsync方法中将ConloccyStamp输入值设置为实体，如下所示：
                                            public class BookAppService : ApplicationService, IBookAppService 
                                            {

                                                public virtual async Task<BookDto> UpdateAsync(Guid id, UpdateBookDto input) 
                                                {
                                                    var book = await BookRepository.GetAsync(id);

                                                    book.ConcurrencyStamp = input.ConcurrencyStamp;

                                                    // 设置其他属性的跟新 ...
                                                    // 使用参数： autoSave: true 来获取最新ConcurrencyStamp
                                                    await BookRepository.UpdateAsync(book, autoSave: true);
                                                }
                                            }

                                        之后，当多个用户尝试同时更新同一条记录时，会发生并发戳不匹配并抛出AbpDbConcurrencyException。你可以手动处理异常，也可以让ABP为你处理。

                                        如果你不手动处理异常，ABP会显示用户友好的错误消息，如下图所示。
                                            
                    */
        </script>
    </body>
</html>